home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / rend10.lzh / REND1.0 / GraphicSubSystem / displaymap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-08  |  8.0 KB  |  287 lines

  1. /*
  2.  * Title:
  3.  *    displaymap.c
  4.  *
  5.  * Authors:
  6.  *     Michael P. Schenck
  7.  *
  8.  * Purpose:
  9.  *     This module impliments an object hierarchy similar to the 
  10.  *    one used in phigs.  It allows subobjects and lists of nodes 
  11.  *    which act as a series of command matricies.  
  12.  *    A root node is always allocated first for an object.  This
  13.  *    is followed by a list of other nodes whos matricies can 
  14.  *    either be appended to the local matrix or can set a new
  15.  *    local matrix to thier own matrix.  All of these nodes can
  16.  *    have models linked to them that will be transformed into
  17.  *     world coordinate (object parts) by using the concatenation
  18.  *    of the matrix from the previous level (if a subobject) and
  19.  *    and the current local matrix.  A subobject is made by linking
  20.  *    another node to the subject link of a node in the previous
  21.  *    level.  An action block (node) can be inserted after any
  22.  *    node already in the objects display map.
  23.  *    There is no current way to remove an individual action block,
  24.  *    only the removal of the entire object.  If either of the 
  25.  *    action block creation functions return NULL, then the nodes
  26.  *    could not be created.  The values returned are pointers to
  27.  *    the blocks allowing access to the matrix, the model, and 
  28.  *    its effect in the display map from a central point. For more
  29.  *    details on the way this hierarchy functions Refer to
  30.  *    Section 7.6 in Computer Graphics, Principles and Practice, 
  31.  *    Foley, VanDam, ect.
  32.  *
  33.  * Copyright Info:
  34.  *    Copyright (C) 1993, 1994 -- by Michael P. Schenck, 
  35.  *    (mps4466@ultb.isc.rit.edu)
  36.  *    
  37.  *    This program is free software; you can redistribute it and/or modify
  38.  *    it under the terms of the GNU General Public License as published
  39.  *    by the Free Software Foundation; either version 2 of the License,
  40.  *    or (at your option) any later version.
  41.  *
  42.  *    This software is distributed in the hope that it will be useful, but
  43.  *    WITHOUT ANY WARRANTY; without even the implied warranty of
  44.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  45.  *    GNU General Public License for more details.
  46.  *
  47.  *      For a copy of the GNU General Public License
  48.  *    write to the Free Software Foundation, 675 Mass Ave,
  49.  *    Cambridge, MA  02139, USA.
  50.  *
  51.  */
  52.  
  53. #include <stdlib.h>
  54. #include "/include/types.h"
  55. #include "/include/matrix.h"
  56. #include "/include/database.h"
  57. #include "/include/displaymap.h"
  58.  
  59. static ULONG curnumobjects;   
  60. static struct Action *roots[MAXROOTOBJECTS];
  61.        
  62. extern struct Model *models[MAXNUMMODELS];
  63. extern struct Object *objects[MAXNUMOBJECTS];
  64.  
  65. void traverseobject(struct Action *,MATRIX);
  66. void traverseactionblock(struct Action *,MATRIX,MATRIX);
  67. void evaluatemodel(ULONG,ULONG,MATRIX);
  68.  
  69.     /* Clears the entire display map. */
  70.  
  71. void cleardisplaymap()
  72.  
  73. {
  74.    ULONG i;
  75.         
  76.    curnumobjects=0;
  77.    for(i=0;i<MAXROOTOBJECTS;i++) {
  78.       if(roots[i] != NULL)
  79.          removeroot(roots[i]);  
  80.       roots[i]=NULL;
  81.    }     
  82. }    
  83.  
  84.     /* Creates a root action for a new object. */
  85.  
  86. struct Action *createrootaction(MATRIX transmatrix,ULONG model)
  87.  
  88. {
  89.    struct Action *new;
  90.    ULONG i;
  91.    
  92.    if (((new=(struct Action *)malloc(sizeof(struct Action))) == NULL)&&(curnumobjects < MAXROOTOBJECTS))
  93.       return(NULL);
  94.    if((new->lm=allocatematrix())==NULL) {
  95.       free((void *)new);
  96.       return(NULL);
  97.    }   
  98.    if((new->cmtm=allocatematrix())==NULL) {
  99.       freematrix(new->lm);
  100.       free((void *)new);
  101.       return(NULL);
  102.    }    
  103.    if(model!=NOMODEL) {
  104.       if((new->object=allocateobject(model))==NOOBJECT) {
  105.      freematrix(new->lm);
  106.      freematrix(new->cmtm);
  107.      free((void *)new);
  108.      return(NULL);
  109.       }
  110.    }   
  111.    else
  112.       new->object = NOOBJECT;
  113.    new->transtype = SET;
  114.    new->changed = TRUE;
  115.    new->transmatrix = transmatrix;
  116.    new->model = model;
  117.    new->previous = NULL;
  118.    new->next = NULL;
  119.    new->subobject = NULL;
  120.    i=0;
  121.    while(roots[i]!=NULL) 
  122.       i++;
  123.    roots[i]=new;   
  124.    curnumobjects++;
  125.    return(new);
  126. }           
  127.  
  128.     /* Inserts a new action block before the one specified in curaction. 
  129.        this block can be a subobject or an object on the same level. */
  130.  
  131. struct Action *createaction(struct Action *curaction,MATRIX transmatrix,UBYTE transtype,ULONG model,UBYTE type)
  132.  
  133. {
  134.    struct Action *new;
  135.      
  136.    if((new=(struct Action *)malloc(sizeof(struct Action))) == NULL)
  137.       return(NULL);
  138.    if((new->lm=allocatematrix())==NULL) {
  139.       free((void *)new);
  140.       return(NULL);
  141.    }   
  142.    if((new->cmtm=allocatematrix())==NULL) {
  143.       freematrix(new->lm);
  144.       free((void *)new);
  145.       return(NULL);
  146.    }   
  147.    if(model!=NOMODEL) {
  148.       if((new->object=allocateobject(model))==NOOBJECT) {
  149.      freematrix(new->lm);
  150.      freematrix(new->cmtm);
  151.      free((void *)new);
  152.      return(NULL);
  153.       }
  154.    }   
  155.    else
  156.       new->object = NOOBJECT;
  157.    new->transtype = transtype;
  158.    new->changed = TRUE;
  159.    new->transmatrix = transmatrix;
  160.    new->model = model;
  161.    new->previous = curaction;
  162.    if(type==CUROBJECT) {
  163.       new->next = curaction->next;
  164.       curaction->next = new;
  165.       new->subobject = NULL;
  166.    }
  167.    else {
  168.       new->subobject = curaction->subobject;
  169.       curaction->subobject = new;
  170.       new->next = NULL;
  171.    }
  172.    return(new);          
  173. }                   
  174.     
  175.     /* Removes an entire object. */ 
  176.     
  177. void removeroot(struct Action *root)
  178.  
  179. {        
  180.    deallocateobject(root->object);     
  181.    freematrix(root->lm);
  182.    freematrix(root->cmtm);
  183.    if(root->subobject != NULL)
  184.       removeaction(root->subobject);
  185.    if(root->next != NULL)
  186.       removeaction(root->next);
  187.    free((void *)root);      
  188. }            
  189.         
  190.     /* Removes an action block and any action blocks below it. */
  191.     
  192. void removeaction(struct Action *curaction)
  193.  
  194. {    
  195.    deallocateobject(curaction->object);
  196.    freematrix(curaction->lm);
  197.    freematrix(curaction->cmtm);
  198.    if(curaction->subobject != NULL)
  199.       removeaction(curaction->subobject);
  200.    if(curaction->next != NULL)
  201.       removeaction(curaction->next);
  202.    free((void *)curaction);     
  203. }
  204.  
  205.     /* Begins traversal of the entire display tree. */
  206.  
  207. void traversedisplaymap()
  208.  
  209. {
  210.    ULONG i;
  211.    MATRIX gm;     
  212.         
  213.    gm=allocatematrix();     
  214.    for(i=0;i<MAXROOTOBJECTS;i++) {
  215.       if(roots[i] != NULL) {
  216.          identitymatrix(gm);
  217.          traverseobject(roots[i],gm);
  218.       }
  219.    }
  220.    freematrix(gm);   
  221. }            
  222.  
  223.     /* Starts traversal of a new object or subobject. */
  224.  
  225. void traverseobject(struct Action *cur,MATRIX gm)
  226.  
  227. {  
  228.    if(cur->changed==TRUE) {
  229.       if((cur->transmatrix!=NULL)&&((cur->transtype==SET)||(cur->transtype==APPEND)))
  230.          copymatrix(cur->transmatrix,cur->lm);
  231.       else 
  232.          identitymatrix(cur->lm);
  233.       multmatrix(cur->lm,gm,cur->cmtm);
  234.       if(cur->model!=NOMODEL)
  235.          evaluatemodel(cur->model,cur->object,cur->cmtm);
  236.       if(cur->next!=NULL)
  237.          cur->next->changed=TRUE;
  238.       if(cur->subobject!=NULL)
  239.          cur->subobject->changed=TRUE;
  240.       cur->changed=FALSE;   
  241.    } 
  242.    if(cur->subobject!=NULL)
  243.       traverseobject(cur->subobject,cur->cmtm);        
  244.    if(cur->next!=NULL)
  245.       traverseactionblock(cur->next,cur->lm,gm);  
  246. }
  247.  
  248.     /* Traverses a single action block. */
  249.  
  250. void traverseactionblock(struct Action *cur,MATRIX lm,MATRIX gm)
  251.  
  252. {
  253.    if(cur->changed==TRUE) {
  254.       switch(cur->transtype) {
  255.          case SET    : copymatrix(cur->transmatrix,cur->lm);
  256.                        break;
  257.          case APPEND : multmatrix(cur->transmatrix,lm,cur->lm);
  258.                        break;
  259.          case NONE   : identitymatrix(cur->lm);
  260.                        break;
  261.       }  
  262.       multmatrix(cur->lm,gm,cur->cmtm);
  263.       if(cur->model!=NOMODEL)
  264.          evaluatemodel(cur->model,cur->object,cur->cmtm);
  265.       if(cur->next!=NULL)
  266.          cur->next->changed=TRUE;
  267.       if(cur->subobject!=NULL)
  268.          cur->subobject->changed=TRUE;
  269.       cur->changed=FALSE;   
  270.    } 
  271.    if(cur->subobject!=NULL)
  272.       traverseobject(cur->subobject,cur->cmtm);        
  273.    if(cur->next!=NULL)
  274.       traverseactionblock(cur->next,cur->lm,gm);  
  275. }  
  276.  
  277.     /* Transform model verticies to object verticies (world coords). */
  278.  
  279. void evaluatemodel(ULONG model,ULONG object,MATRIX transmatrix)
  280.  
  281. {
  282.    ULONG i;
  283.        
  284.    for(i=0;i<(models[model]->numvert*4);i+=4)
  285.       multvecandmat(models[model]->verticies+i,transmatrix,objects[object]->verticies+i);         
  286. }              
  287.